#include "ptr.h"

using namespace std;
using namespace opsrc::stdf;
#include "rectype.h"
#include "util.h"

#include "nmfield.h"
#include "nmfield.cpp"

#include "cnfield.h"

#include "nmarrfield.h"
#include "nmarrfield.cpp"

Ptr::Ptr()
{}

Ptr::Ptr(stdf_rec _stdfrec,  int _reclen, std::ios::pos_type _fileRecFirstBytePosition, int _orderindex, endian e, char* buf)
:RecBase(_stdfrec, _reclen, _fileRecFirstBytePosition, _orderindex),en(e) {
    if (buf!=0)
        readFields(buf);
}


Ptr::~Ptr() {
}

const StdfField<long> Ptr::getTestNumber() const {
    return test_num;
}

void Ptr::setTestNumber(StdfField<long> testnum) {
    test_num = testnum;
}

const StdfField<int> Ptr::getHeadNumber() const {
    return head_num;
}

void Ptr::setHeadNumber(StdfField<int> headnum) {
    head_num = headnum;
}

const StdfField<int> Ptr::getSiteNumber() const {
    return site_num;
}

void Ptr::setSiteNumber(StdfField<int> sitenum) {
    site_num = sitenum;
}

const StdfField<vector<bool> > Ptr::getTestFlag() const {
    return test_flag;
}

void Ptr::setTestFlag(StdfField<vector<bool> > testflag) {
    test_flag = testflag;
}

const StdfField<vector<bool> > Ptr::getParaTestFlag() const {
    return paratest_flag;
}

void Ptr::setParaTestFlag(StdfField<vector<bool> > paratestflag ) {
    paratest_flag = paratestflag;
}

const StdfField<float> Ptr::getResult() const {
    return result;
}

void Ptr::setResult(StdfField<float> result) {
    this->result = result;
}

const StdfField<string> Ptr::getTestText() const {
    return test_txt;
}

void Ptr::setTestText(StdfField<string> testtxt) {
    test_txt = testtxt;
}

const StdfField<string> Ptr::getAlarmId() const {
    return alrm_id;
}

void Ptr::setAlarmId(StdfField<string> alrmid) {
    alrm_id = alrmid;
}

const StdfField<vector<bool> > Ptr::getOptionFlag() const {
    return opt_flag;
}

void Ptr::setOptionFlag(StdfField<vector<bool> > optionflag) {
    opt_flag = optionflag;
}

const StdfField<int> Ptr::getResultScale() const {
    return result_scal;
}

void Ptr::setResultScale(StdfField<int> _resultscal) {
    result_scal = _resultscal;
}

const StdfField<int> Ptr::getLowerLimitScale() const {
    return lwlimit_scal;
}

void Ptr::setLowerLimitScale(StdfField<int> lwlimitscal) {
    lwlimit_scal = lwlimitscal;
}

const StdfField<int> Ptr::getUpperLimitScale() const {
    return uplimit_scal;
}

void Ptr::setUpperLimitScale(StdfField<int> uplimitscal) {
    uplimit_scal = uplimitscal;
}

const StdfField<float> Ptr::getLowerTestLimitValue() const {
    return lowtestlimit_val;
}


void Ptr::setLowerTestLimitValue(StdfField<float> lowtestlimitval) {
    lowtestlimit_val = lowtestlimitval;
}

const StdfField<float> Ptr::getUpperTestLimitValue() const {
    return hightestlimit_val;
}

void Ptr::setUpperTestLimitValue(StdfField<float> hightestlimitval) {
    hightestlimit_val = hightestlimitval;
}

const StdfField<string> Ptr::getResultsUnit() const {
    return res_units;
}

void Ptr::setResultsUnit(StdfField<string> resunits) {
    res_units = resunits;
}

const StdfField<string> Ptr::getResultFormat() const {
    return result_fmt;
}

void Ptr::setResultFormat(StdfField<string> resultfmt) {
    result_fmt = resultfmt;
}

const StdfField<string> Ptr::getLowerLimitScaleFormat() const {
    return lwlimit_scal_fmt;
}
void Ptr::setLowerLimitScaleFormat(StdfField<string> lwlimitscalfmt) {
    lwlimit_scal_fmt = lwlimitscalfmt;
}

const StdfField<string> Ptr::getUpperLimitScaleFormat() const {
    return  uplimit_scal_fmt;
}

void Ptr::setUpperLimitScaleFormat(StdfField<string> uplimitscalfmt) {
    uplimit_scal_fmt = uplimitscalfmt;
}

const StdfField<float>	Ptr::getLowerLimitSpec() const {
    return lwlimit_spec;
}

void Ptr::setLowerLimitSpec(StdfField<float> lwlimitspec) {
    lwlimit_spec = lwlimitspec;
}

const StdfField<float>	Ptr::getUpperLimitSpec() const {
    return uplimit_spec;
}

void Ptr::setUpperLimitSpec(StdfField<float> uplimitspec) {
    uplimit_spec = uplimitspec;
}

//const StdfField<int> Ptr::getXCoordinate() const {
//    return x_coord;
//}

//void Ptr::setXCoordinate(StdfField<int> xcoord) {
//    x_coord = xcoord;
//}

//const StdfField<int> Ptr::getYCoordinate() const {
//    return y_coord;
//}

//void Ptr::setYCoordinate(StdfField<int> ycoord) {
//    y_coord = ycoord;
//}

void Ptr::readFields(char *buf) {

#if _DEBUG
    cout << "stdfrec= PTR , filebytestartposition= " <<   getFileRecByteStartPosition() << ", recbytecount= " << reclen <<endl;
#endif

    int curpos = 0;
    // Read test number , 4 byte
    NmField<long, 4> testnum(buf+curpos, en);
    test_num.set(testnum.getData(), curpos, testnum.getByteCount(), testnum.getTotalByteCount());
    curpos += test_num.getTotalByteCount();

    // Read head number , 1 byte
    if (curpos < reclen-1) {
        NmField<unsigned int, 1> headnum(buf+curpos, en);
        head_num.set(headnum.getData(), curpos, headnum.getByteCount(), headnum.getTotalByteCount());
        curpos += head_num.getTotalByteCount();
    }

    // Read site num, 1 byte
    if (curpos < reclen-1) {
        NmField<unsigned int, 1> sitenum(buf+curpos, en);
        site_num.set(sitenum.getData(), curpos, sitenum.getByteCount(), sitenum.getTotalByteCount());
        curpos += site_num.getTotalByteCount();
    }

    // Read test flag
    if (curpos < reclen-1) {
        NmArrField<bool, 1 > testflag(buf+curpos, en, 1);
        test_flag.set(testflag.getData(), curpos, testflag.getByteCount(), testflag.getTotalByteCount());
        curpos += test_flag.getTotalByteCount();
    }


    // Read paratest flag
    if (curpos < reclen-1) {
        NmArrField<bool, 1 > paratestflag(buf+curpos, en, 1);
        paratest_flag.set(paratestflag.getData(), curpos, paratestflag.getByteCount(), paratestflag.getTotalByteCount());
        curpos += paratest_flag.getTotalByteCount();
    }


    // Read result, 4 bytes
    if (curpos < reclen-1) {
        NmField<float, 4> res(buf+curpos, en);
        result.set(res.getData(), curpos, res.getByteCount(), res.getTotalByteCount());
        curpos += result.getTotalByteCount();
    }

    // read result text
    if (curpos < reclen-1){
        CnField<string> testtxt(buf+curpos, en);
        test_txt.set(testtxt.getData(), curpos, testtxt.getByteCount(), testtxt.getTotalByteCount());
        curpos += test_txt.getTotalByteCount();
    }

    // Read result text
    if (curpos < reclen-1) {
        CnField<string> alrmid(buf+curpos, en);
        alrm_id.set(alrmid.getData(), curpos, alrmid.getByteCount(), alrmid.getTotalByteCount());
        curpos += alrm_id.getTotalByteCount();
    }

    if( curpos == reclen)
    {
        return;
    }

    // Read option flag
    if (curpos < reclen-1) {
        NmArrField<bool, 1 > optflag(buf+curpos, en, 1);
        opt_flag.set(optflag.getData(), curpos, optflag.getByteCount(), optflag.getTotalByteCount());
        curpos += opt_flag.getTotalByteCount() ;
        string s = optflag.arrayToString();

        if( optflag.at(0) == "0")
        {
            // Read result scale
            NmField<short, 1 > resultscal(buf+curpos, en);
            result_scal.set(resultscal.getData(), curpos, resultscal.getByteCount(), resultscal.getTotalByteCount());
            curpos += resultscal.getTotalByteCount();
        }

        // Read lower limit scale
        if( ( optflag.at(4) != "1") && ( optflag.at(6) != "1") )
        {
            NmField<short, 1 > lwlimitscal(buf+curpos, en);
            lwlimit_scal.set(lwlimitscal.getData(), curpos, lwlimitscal.getByteCount(), lwlimitscal.getTotalByteCount());
            curpos += lwlimitscal.getTotalByteCount();
        }

        // Read upper limit scale
        if( ( optflag.at(5) != "1") && ( optflag.at(7) != "1") )
        {
            NmField<short, 1 > uplimitscal(buf+curpos, en);
            uplimit_scal.set(uplimitscal.getData(), curpos, uplimitscal.getByteCount(), uplimitscal.getTotalByteCount());
            curpos += uplimitscal.getTotalByteCount();
        }

        // Read lower test limit value
        NmField<float, 4 > * pLowtestlimitval = 0;
        if( ( optflag.at(4) != "1") && ( optflag.at(6) != "1") )
        {
            pLowtestlimitval = new NmField<float, 4 >(buf+curpos, en);
            lowtestlimit_val.set(pLowtestlimitval->getData(), curpos, pLowtestlimitval->getByteCount(), pLowtestlimitval->getTotalByteCount());
            curpos += pLowtestlimitval->getTotalByteCount();
        }

        // Read upper test limit value
        NmField<float, 4 > * pHightestlimitval = 0;
        if( ( optflag.at(5) != "1") && ( optflag.at(7) != "1") )
        {
            pHightestlimitval = new NmField<float, 4 >(buf+curpos, en);
            hightestlimit_val.set(pHightestlimitval->getData(), curpos, pHightestlimitval->getByteCount(), pHightestlimitval->getTotalByteCount());
            curpos += pHightestlimitval->getTotalByteCount();
        }

        // Read Test units
        CnField<string> resunits(buf+curpos, en);
        res_units.set(resunits.getData(), curpos, resunits.getByteCount(), resunits.getTotalByteCount());
        curpos += res_units.getTotalByteCount();

        // Read result format string
        CnField<string> resultfmt(buf+curpos, en);
        result_fmt.set(resultfmt.getData(), curpos, resultfmt.getByteCount(),resultfmt.getTotalByteCount());
        curpos += result_fmt.getTotalByteCount();

        // Read low limit format string
        CnField<string> lwlimitscalfmt(buf+curpos, en);
        lwlimit_scal_fmt.set(lwlimitscalfmt.getData(), curpos, lwlimitscalfmt.getByteCount(), lwlimitscalfmt.getTotalByteCount());
        curpos += lwlimit_scal_fmt.getTotalByteCount();

        // Read upper limit format string
        CnField<string> uplimitscalfmt(buf+curpos, en);
        uplimit_scal_fmt.set(uplimitscalfmt.getData(), curpos, uplimitscalfmt.getByteCount(), uplimitscalfmt.getTotalByteCount());
        curpos += uplimit_scal_fmt.getTotalByteCount();

        // Read lower spec limit value
        if( optflag.at(2) != "1" )
        {
            NmField <float, 4> lwlimitSpec(buf+curpos, en);
            lwlimit_scal.set(lwlimitSpec.getData(), curpos, lwlimitSpec.getByteCount(), lwlimitSpec.getTotalByteCount());
            curpos += lwlimitSpec.getTotalByteCount();
        }

        // Read upper spec limit value
        if( optflag.at(3) != "1" )
        {
            NmField<float, 4> uplimitspec(buf+curpos, en);
            uplimit_scal.set(uplimitspec.getData(), curpos, uplimitspec.getByteCount(), uplimitspec.getTotalByteCount());
            curpos += uplimitspec.getTotalByteCount();
        }
    }
}
